﻿using Common.Contract;
using Common.Contract.Customer;
using Common.Contract.Customer.Request;
using Common.Contract.SaleOut;
using Common.Contract.SaleOut.Request;
using Common.Contract.Warranty.Request;
using Common.Service;
using Common.Service.Command;
using Common.Util;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Warranty.Configuration;
using Warranty.Model.Interface;
using Warranty.Model.Model;

namespace Warranty.ServiceCommand
{
    public class ConfirmSaleOutServiceCommand : ProviderServiceCommand<IProviderFactory, ConfirmSaleOutRequest, ResponseRecord>
    {
        public ConfirmSaleOutServiceCommand(IProviderFactory provider) : base(provider) { }

        protected override void Validate(ConfirmSaleOutRequest request)
        {
            if (request == null) throw new ArgumentNullException("request");
            if (!request.Header.ApplicationKey.HasValue || request.Header.ApplicationKey == Guid.Empty)
            {
                throw new ArgumentException("ApplicationKey must be set", "request");
            }
            if (request.Header.UserRequest.IsNullOrWhiteSpace())
            {
                throw new ArgumentException("User request must be set", "request");
            }

            if (request.Record == null || !request.Record.SaleOutDate.HasValue)
            {
                throw new ArgumentException("SaleOutDate request must be set", "request");
            }

            if (request.Record.SeriaNumber.IsNullOrWhiteSpace())
            {
                throw new ArgumentException("SeriaNumber request must be set", "request");
            }
        }

        protected override bool OnExecute(ResponseRecord response)
        {
            //STEP1 UPDATE_SN_SO_WT_MST
            UpdateWarrantyMessage();

            //STEP2 GET_WT_RESPONSE
            int totalYear;
            string respFlag;
            string responseMSG = BuildResponseSMS(out totalYear, out respFlag);

            //STEP3 UPDATE_SN_SO_WT_HIST
            var messageType = UpdateWarrantyMessageHistory(responseMSG, totalYear, respFlag);

            //STEP4: UPDATE_TB_MT_HIST
            UpdateMessageHistory(messageType, responseMSG);

            //STEP5 UPDATE_TB_SN_SO_DEALERS
            UpdateDealerStatus();

            //UPDATE tb_sn_rdc_hist & tb_sn_cdc_hist
            UpdateRDCAndCDC();
            return true;
        }

        private void UpdateRDCAndCDC()
        {
            var record = Request.Record;
            var header = new RequestHeaderRecord
            {
                ApplicationKey = Request.Header.ApplicationKey,
                CallerName = "Warranty.ServiceCommand.ConfirmSaleOutServiceCommand"
            };

            using (ServiceClient<ISaleOut> serviceClient = new ServiceClient<ISaleOut>())
            {
                //UPDATE tb_sn_rdc_hist
                RetrieveRdcHistRequest requestRdc = new RetrieveRdcHistRequest
                {
                    Header = header,
                    SerialNo = record.SeriaNumber,
                    Model = record.Model,
                    Suffix = record.Suffix
                };
                var responseRdc = serviceClient.Proxy.RetrieveRdcHistory(requestRdc);
                if (responseRdc.IsSuccess && responseRdc.Record != null)
                {
                    var recordRdc = responseRdc.Record;
                    recordRdc.SelloutStatus = BooleanString.TRUE;

                    UpdateRdcHistRequest requestUpdateRdc = new UpdateRdcHistRequest
                    {
                        Header = header,
                        Record = recordRdc
                    };
                    serviceClient.Proxy.UpdateRdcHistory(requestUpdateRdc);
                }


                //UPDATE tb_sn_cdc_hist
                RetrieveCdcHistRequest requestCdc = new RetrieveCdcHistRequest
                {
                    Header = header,
                    SerialNo = record.SeriaNumber,
                    Model = record.Model,
                    Suffix = record.Suffix
                };
                var responseCdc = serviceClient.Proxy.RetrieveCdcHistory(requestCdc);
                if (responseCdc.IsSuccess && responseCdc.Record != null)
                {
                    var recordCdc = responseCdc.Record;
                    recordCdc.SelloutFlag = true;

                    UpdateCdcHistRequest requestUpdateCdc = new UpdateCdcHistRequest
                    {
                        Header = header,
                        Record = recordCdc
                    };
                    serviceClient.Proxy.UpdateCdcHistory(requestUpdateCdc);
                }
            }
        }

        private void UpdateDealerStatus()
        {
            var record = Request.Record;
            var provider = Providers.Dealers;
            Dealer dealer = provider.RetrieveDealer(record.ShopInfo.ShopCode, record.EdiNumber, record.SaleOutDate);
            dealer.CfmFlag = BooleanString.TRUE;
            dealer.CfmUser = Request.Header.UserRequest;
            dealer.CfmComment = record.ConfirmComment;
            dealer.CfmDate = DateTime.Now;
            var xx = provider.Update(dealer);
        }


        /// <summary>
        /// FN_GET_WT_RESPONSE
        /// </summary>
        private string BuildResponseSMS(out int numbYear, out string respFlag)
        {
            string result = string.Empty;
            numbYear = 0;
            respFlag = SystemConfiguration.DEFAULT_RESP_FLAG;
            // (wt_end_date - wt_start_date)/(365-1)  
            //TB_SN_SO_WT_MST0
            List<WarrantyMessage> list0 = Providers.WarrantyMessage.Search(Request.Record.SeriaNumber, Request.Record.Model);

            //TB_SN_SO_WT_MST
            List<WarrantyMaster> list = Providers.WarrantyMaster.Search(Request.Record.SeriaNumber, Request.Record.Model);

            if (list0 != null && list != null && list.Count + list0.Count > 1)
            {
                respFlag = SystemConfiguration.MULTI_RESP_FLAG;
            }
            else if ((list0 == null || list0.Count == 0) && (list == null || list.Count == 0))
            {
                respFlag = SystemConfiguration.FALSE_RESP_FLAG;
            }
            else if (list != null && list.Count == 1 && list[0].StartDate.HasValue)
            {
                result = "$" + list[0].Model + ", Serial/IMEI " + list[0].SerialNo + "$" + list[0].StartDate.Value.ToString(SystemConfiguration.LocalDateTimeFormat);
                if (list[0].EndDate.HasValue)
                {
                    numbYear = (int)((list[0].EndDate.Value - list[0].StartDate.Value).TotalDays / 364);
                }
            }
            else if (list0 != null && list0.Count == 1 && list0[0].StartDate.HasValue)
            {
                result = "$" + list0[0].Model + ", Serial/IMEI " + list0[0].SerialNo + "$" + list0[0].StartDate.Value.ToString(SystemConfiguration.LocalDateTimeFormat);
                if (list0[0].EndDate.HasValue)
                {
                    numbYear = (int)((list0[0].EndDate.Value - list0[0].StartDate.Value).TotalDays / 364);
                }
            }

            return result;
        }


        /// <summary>
        /// PR_UPDATE_SN_SO_WT_MST
        /// </summary>
        private void UpdateWarrantyMessage()
        {
            var record = Request.Record;
            var shopRecord = Request.Record.ShopInfo;
            var header = new RequestHeaderRecord
            {
                ApplicationKey = Request.Header.ApplicationKey,
                CallerName = "Warranty.ServiceCommand.ConfirmSaleOutServiceCommand"
            };
            string schemeId = "", productL1 = "OTHERS";
            int extendFays = 0;
            DateTime? enddate = null;
            using (ServiceClient<ICustomer> serviceClient = new ServiceClient<ICustomer>())
            {
                //===========================TB_CM_MODEL_CAT=======================
                SearchModelCatRequest requestModelCat = new SearchModelCatRequest
                {
                    Header = header,
                    Model = record.Model
                };

                var responseShops = serviceClient.Proxy.SearchModelCat(requestModelCat);
                if (responseShops.IsSuccess && responseShops.Records.Count > 0)
                {
                    productL1 = responseShops.Records.GroupBy(x => x.ProdL1).Select(x => x.FirstOrDefault().ProdL1).FirstOrDefault();
                }
                string[] type1 = new string[] { "MN", "MNT" };
                string[] type2 = new string[] { "WM", "RF", "VT" };
                string[] type3 = new string[] { "AC" };
                if (record.SaleOutDate.HasValue)
                {
                    if (type1.Any(x => x.ToUpper() == productL1.ToUpper()))
                    {
                        enddate = record.SaleOutDate.Value.AddDays((365 - 1) * 2);
                    }
                    else if (type2.Any(x => x.ToUpper() == productL1.ToUpper()) && DateTime.Today >= new DateTime(2014, 10, 1))
                    {
                        enddate = record.SaleOutDate.Value.AddDays((365 - 1) * 2);
                    }
                    else if (type3.Any(x => x.ToUpper() == productL1.ToUpper()) && DateTime.Today >= new DateTime(2015, 2, 1))
                    {
                        enddate = record.SaleOutDate.Value.AddDays((365 - 1) * 2);
                    }
                    else
                    {
                        //===========================TB_CM_INCENTIVE_ADHOC=======================
                        RetrieveIncentiveAdhocRequest requestAdhoc = new RetrieveIncentiveAdhocRequest
                        {
                            Header = header,
                            SelloutDate = record.SaleOutDate.Value
                        };
                        var responseAdhoc = serviceClient.Proxy.RetrieveIncentiveAdhoc(requestAdhoc);
                        if (responseAdhoc.IsSuccess)
                        {
                            schemeId = responseAdhoc.Record.SchemeId;
                        }

                        //===========================TB_CM_INCENTIVE_ADHOC_DETAIL=================
                        RetrieveAdhocDetailRequest requestAdhocDetail = new RetrieveAdhocDetailRequest
                        {
                            Header = header,
                            BillToCode = record.BillCode,
                            Model = record.Model,
                            SchemeId = schemeId
                        };
                        var responseAdhocDetail = serviceClient.Proxy.RetrieveAdhocDetail(requestAdhocDetail);
                        if (responseAdhocDetail.IsSuccess)
                        {
                            extendFays = responseAdhocDetail.Record.Amt.ToInt();
                            if (extendFays <= 0)
                                enddate = record.SaleOutDate.Value.AddDays(extendFays);
                            else
                                enddate = record.SaleOutDate.Value.AddDays(365 - 1);
                        }
                    }
                }
            }

            WarrantyMaster wSms = new WarrantyMaster
            {
                ShopCode = shopRecord.ShopCode,
                ShopCell = shopRecord.CellNo1,
                SerialNo = record.SeriaNumber,
                Model = record.Model,
                Suffix = record.Suffix,
                SellinDate = record.SaleInDate,
                SelloutDate = record.SaleOutDate,
                SelloutTime = DateTime.Now.ToString("HHmmss"),
                StartDate = record.SaleOutDate,
                EndDate = enddate,
                SelloutRespType = SystemConfiguration.WT_SN_VL,
                //SelloutRespMsg = record.
                Point = "0",
                Amt="0",
                SmsYn = BooleanString.FALSE,
                EndUserCell = record.UserCell,
                IncentiveCfmFlag = BooleanString.TRUE,
                IncentiveCfmDate = DateTime.Now,
                CloseFlag = BooleanString.FALSE,
                CreateDate = DateTime.Now
            };
            Providers.WarrantyMaster.Add(wSms);
        }


        /// <summary>
        /// PR_UPDATE_SN_SO_WT_HIST
        /// </summary>
        private string UpdateWarrantyMessageHistory(string responseMsg, int numbYear, string respFlag)
        {
            var record = Request.Record;
            var shopRecord = Request.Record.ShopInfo;
            string messageType = SystemConfiguration.WT_SN_VL;
            if (respFlag == SystemConfiguration.DEFAULT_RESP_FLAG)
            {
                if (numbYear == 1)
                {
                    messageType = SystemConfiguration.WT_S1_VL12;
                }
                else if (numbYear == 2)
                {
                    messageType = SystemConfiguration.WT_S1_VL24;
                }
            }

            WarrantyHistory wSms = new WarrantyHistory
            {
                Cmdcode = SystemConfiguration.CMD_CODE_WARRANTY,
                CreateDate = DateTime.Now,
                EdiFile = null,
                EdiHead = null,
                EndUserCell = record.UserCell,
                Model = record.Model,
                MoMsgbody = SystemConfiguration.MO_SMS_BODY,
                Moseq = record.EdiNumber,
                ReceiveDate = record.SaleOutDate,
                RespMsg = responseMsg,
                RespType = messageType,
                SerialNo = record.SeriaNumber,
                ShopCode = shopRecord.ShopCode,
                ShopCell = shopRecord.CellNo1,
                SmsYn = BooleanString.TRUE,
                SuccessFlag = BooleanString.TRUE

            };
            Providers.WarrantyHistory.Add(wSms);
            return messageType;
        }

        /// <summary>
        /// UPDATE_TB_MT_HIST
        /// </summary>
        private void UpdateMessageHistory(string messageType, string responseMSG)
        {
            var record = Request.Record;
            MessageHistory wSms = new MessageHistory
            {
                Msgtype = SystemConfiguration.MSG_TYPE_TEXT,
                Shortcode = SystemConfiguration.MSG_SHORT_CODE,
                Moseq = "0",
                CellNo = record.UserCell,
                Cmdcode = SystemConfiguration.CMD_CODE_WARRANTY,
                RespType = messageType,
                Msgbody = responseMSG,
                MoMsgbody = (record.ShopInfo == null ? string.Empty : record.ShopInfo.ShopCode) + " EDI",
                MoReceiveTime = record.SaleOutDate,
                SendFlag = BooleanString.TRUE,
                TotalSeq = "1",
                Mtseqref="1",
                CreateDate = DateTime.Now,

            };
            Providers.MessageHistory.Add(wSms);
        }
    }
}
